let person = { name: 'hxb', age: 21 };
Object.defineProperty(person, 'newName', {
  get: function () {
    console.log('get...');
    return this.name;
  },
  set: function (newValue) {
    this.name = newValue;
    console.log('set...', newValue);
  }
});
console.log(person.newName); // get...，hxb
person.newName = 'oqm'; // set...，oqm
console.log(person.newName); // get...，oqm
console.log(person.name); // oqm
// 或者
function defineReactive(obj, key) {
  var value = obj[key] || '没有初始值'; // 采用闭包保存数据，且保持独立。
  Object.defineProperty(obj, key, {
    get: function () {
      console.log('get...');
      return value;
    },
    set: function (newValue) {
      value = newValue;
      console.log('set...', newValue);
    }
  });
}
defineReactive(person, 'name');
console.log(person.name); // get...，'hxb'
person.name = 'oqm'; // set... 'oqm'
console.log(person.name); //  get...，'oqm'

/* ------------------------------ 分割线 ------------------------------ */

let obj = { name: 'hxb', age: 21 };
let proxyObj = new Proxy(obj, {
  get: function (target, key) {
    console.log('get...', target, key);
    return key in target ? target[key] : 'not found';
  },
  set: function (target, key, value) {
    console.log('set...', target, key, value);
    target[key] = value;
    return true;
  }
});
console.log(proxyObj.a); // get... {name: 'hxb', age: 21} a，not found
console.log(proxyObj.name); // get... {name: 'hxb', age: 21} name，hxb
proxyObj.name = 'oqm'; // set... {name: 'hxb', age: 21} name，oqm
console.log(proxyObj); // Proxy {name: 'oqm', age: 21}
console.log(obj); // {name: 'oqm', age: 21}
obj.name = 'test'; // 不会触发 set
console.log(proxyObj); // Proxy {name: 'test', age: 21}
console.log(obj); // {name: 'test', age: 21}